package OrenSvr
import (
	"fmt"
	"net/http"
	"time"
	"os"
	"html/template"
	"io/ioutil"
	"bufio"
	"strings"
	"io"
	"oren/oxml"
)

//const BIG_ENDIAN = 0
//const LITTLE_ENDIAN = 1
//func readString(b []byte) (string, int32, error) {
//	lens := int32(binary.LittleEndian.Uint32(b))
//	fmt.Println("lens :",lens)
//	if lens > 0 {
//		tlens := 4+lens
//		return string(b[4:tlens]), tlens, nil
//	}
//	return "", 4, nil
//}
//
//func readBoolean(b []byte, offset, endian int) bool {
//	re := false
//	if(b[offset] == 1) {
//		re = true
//	}
//	return re
//}

//S 파일 처리 함수들 ---------------------------------------------------
type Page struct {
	Title   string
	Body    []byte
}

func loadPage(filename string) (*Page, error) {
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: filename, Body: body}, nil
}
func (p *Page) save() error {
	filename := p.Title
	return ioutil.WriteFile(filename, p.Body, 0600)
}

func CopyFile(src, dst string) (int64, error) { 
	sf, err := os.Open(src) 
	if err != nil { 
		return 0, err 
	} 
	df, err := os.Create(dst)
	if err != nil { 
		return 0, err 
	} 
	return io.Copy(df, sf) 
} 
//E 파일 처리 함수들 ---------------------------------------------------

func root(w http.ResponseWriter, r *http.Request) {
	if(bDebug) {
		fmt.Println("Root...");
	}
	w.Header().Set("Content-Type", "text/html")
	if r.URL.Path == "/" {
		w.Write([]byte("<h1>Welcome to OrenNamu Web Server !</h1><p><h2>COPYRIGHT (C)2010 OrenNamu Ltd All RIGHTS RESERVED</h2>"))
		return
	}
	inName := webroot + r.URL.Path
	strlen := len(r.URL.Path)
	ext := r.URL.Path[strlen-4:strlen]
	js := r.URL.Path[strlen-3:strlen]
	if ext == "html" || ext == ".htm" {
		t, err := template.ParseFiles(inName)
		if err != nil {
//			http.Error(w, string(err1), http.StatusInternalServerError)
			w.Write([]byte("<h2>Not Found !</h2><p><h3>"+r.URL.Path+"</h3>"))
			return
		}
	    err = t.Execute(w, t)
		if err != nil {
//			http.Error(w, "err", http.StatusInternalServerError)
			w.Write([]byte("<h2>Loading Fial !</h2><p><h3>"+r.URL.Path+"</h3>"))
			return
		}
	} else if ext == ".xml" {
		w.Header().Set("Content-Type", "text/xml")
		p, err := loadPage(inName)
		if(err == nil) {
			w.Write(p.Body)
			if(bDebug) {
				fmt.Println(r.URL.Path+"...")
			}
			return
		} else {
			w.Write([]byte("<h2>Loading Fial !</h2><p><h3>"+r.URL.Path+"</h3>"))
		}
	} else if js == ".js" {
		w.Header().Set("Content-Type", "text/script")
		p, err := loadPage(inName)
		if(err == nil) {
			w.Write(p.Body)
			if(bDebug) {
				fmt.Println(r.URL.Path+"...")
			}
			return
		} else {
			w.Write([]byte("<h2>Loading Fial !</h2><p><h3>"+r.URL.Path+"</h3>"))
		}
	} else {
		format := "image/png"
		size := len(inName)
		switch inName[size-3:size] {
			case "jpg","peg" : format = "image/jpg"
			case "gif": format = "image/gif"
			case "ico": format = "image/ico"
		}
		if(bDebug) {
			fmt.Println(r.URL.Path+"...")
		}
		w.Header().Set("Content-Type", format)
	    inFile, inErr := os.Open(inName) //  , os.O_RDONLY, inPerm); 
	    if inErr == nil {
	    	inBuf := make([]byte, 2048)
	    	n, inErr := inFile.Read(inBuf)
	    	w.Write(inBuf[0:n])
	    	for inErr == nil {
	    		n, inErr = inFile.Read(inBuf);
	    		w.Write(inBuf[0:n])
	    	}
		    inErr = inFile.Close();
	    } else {
			fmt.Println("OrenNamu Web Service Error : ", inErr)
	    }
	    return
	}
}

var exeroot = "D:/workspace/OrenSvr/res"
var bDebug = true
var webroot = "D:/workspace/OrenSvr/res"
var orenroot = "D:/workspace/OrenSvr/res"
var host = "localhost:9031"
var lastId int32
var xmlOren,xmlDataset,xmlLayerset,xmlScheme *oxml.Document

func main() {
	fmt.Println("OrenNamu Web Server starting ...", time.Now)
	lastId = 0
   	ff, err := os.Open(exeroot+"on.properties")
	defer ff.Close()
   	if(err == nil) {
	    f := bufio.NewReader(ff) 
	    for { 
	        read_line, _ := f.ReadString('\n')
	        strs := strings.Split(read_line, "=")
	        if(len(strs) > 1) {
				strs[1] = strings.Trim(strs[1], "\n")
		        strs[1] = strings.Trim(strs[1], "\r")
		        switch strs[0] {
		        	case "host":
		        		if( strs[1] != "") {
		        	 		host = strs[1]
		        	 	}
		        	case "webroot":
		        		if( strs[1] != "") {
		        	 		webroot = strs[1]
		        	 	}
		        	case "orenroot":
		        		if( strs[1] != "") {
		        	 		orenroot = strs[1]
		        	 	}
		        	case "debug": 
		        		if strs[1] == "true" {
		        			bDebug = true
		        		} else {
		        			bDebug = false
		        		} 
		        }
		        fmt.Println("Priperties " + strs[0] + " : " + strs[1]) 
	        }
	        if (read_line == "") { break }
	    }
	    fmt.Println("on.properties file load Success..")
    } else {
    	fmt.Println("on.properties file load fail : ", err)
    }
	fi, err := os.Stat(orenroot+"/conf")
	if fi == nil && err != nil {
		fmt.Println("Make conf diractory..")
		os.Mkdir(orenroot+"/conf", 0600)
 	} 
 	fi, err = os.Stat(orenroot+"/conf/OrenNamu.xml")
	if fi == nil && err != nil {
		fmt.Println("Make OrenNamu.xml file..")
		_, err = CopyFile(exeroot + "/conf/OrenNamu.xml", orenroot+"/conf/OrenNamu.xml")
		if(err != nil) {
			fmt.Println("file make fail.. : ", err)
		}
	}
	
	fmt.Print("Loading OrenNamu.xml file... ")
	xmlOren, err = oxml.ParserFile(orenroot+"/conf/OrenNamu.xml")
	if(err != nil) {
		fmt.Println("Fail! -> ",err)
	} else {
		fmt.Println("Success!")
		if bDebug {
			fmt.Println(xmlOren.XmlToString())
		}
	}


	http.Handle("/", http.HandlerFunc(root))
	
	fmt.Println("======================================================");
	fmt.Println("  OrenNamu Web Server ");
	fmt.Println("  Release Version 0.0.1");
	fmt.Println("  Copyright @ 2014 by OrenNamu All right reserved");
	fmt.Println("  Tel	 : +82-70");
	fmt.Println("  Release Date : 2014/09/17");
	fmt.Println("======================================================");
	fmt.Println("  Read Configuration!");
	fmt.Println("======================================================");
	
	fmt.Println("OrenNamu Server started ! Ready...")

    svrerr := http.ListenAndServe(host, nil)
    if svrerr != nil {
       fmt.Printf("OrenNamu Service Error : ", err)
    }
}
